﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using Exceptions;

namespace AddressBookModel
{
    public abstract class Contact : IContact, ISerializableContact
    {
        private static List<Contact> contacts = new List<Contact>();
        protected StringBuilder contact = new StringBuilder();

        public static List<Contact> Contacts
        {
            get { return contacts; }
        }
        public string Name { get; set; }
        public DateTime? Birthday { get; set; }
        public string PhoneNumber { get; set; }
        public string Email { get; set; }
        public string Icon { get; set; }
        public ContactGroup Group { get; set; }
        public string Picture { get; set; }
        public bool UpcomingBirthday { get; private set; }

        public Contact() { }

        public Contact(string name, string telNumber, string email, DateTime? birthday)
        {
            this.Name = name;
            this.PhoneNumber = telNumber;
            this.Email = email;
            this.Birthday = birthday;
            this.CheckForBirthday();
        }

        public virtual string Serialize()
        {
            contact.Append(this.Name + "|");
            contact.Append(this.PhoneNumber + "|");
            contact.Append(this.Email + "|");

            if (this.Birthday.HasValue)
            {
                DateTime date = this.Birthday.Value;
                contact.Append(date.Day + "." + date.Month + "." + date.Year + "|");
            }
            else contact.Append("|");

            contact.Append(Path.GetFileName(this.Picture));

            return this.contact.ToString();
        }

        public abstract Contact Deserialize(string person);

        public static void AddContact(Contact contact)
        {
            contacts.Add(contact);
        }

        public static void ValidateContact(string name, string mobile, string birthday)
        {
            DateTime date;
            bool isDate = DateTime.TryParse(birthday, out date);

            if (name.Trim() == "")
            {
                throw new AddressBookException("Name is mandatory!", new InvalidNameException());
            }
            if (mobile.Trim() == "")
            {
                throw new AddressBookException("Mobile phone is mandatory!", new InvalidPhoneException());
            }
            if (birthday.Trim() != "")
            {
                if (!isDate)
                {
                    throw new InvalidDateException("Enter correct date!");
                }
            }
            if (mobile.Trim() != null)
            {
                string tel = mobile.Trim();
                for (int i = 0; i < tel.Length; i++)
                {
                    if (!char.IsDigit(tel[i]))
                    {
                        throw new InvalidPhoneException("Enter valid mobile number!");
                    }
                }
            }
        }

        public void CheckForBirthday()
        {
            if (this.Birthday.HasValue)
            {
                DateTime start = DateTime.Now;
                DateTime end = DateTime.Now.AddDays(4);

                int day = this.Birthday.GetValueOrDefault().Day;
                int month = this.Birthday.GetValueOrDefault().Month;

                if (start.Month == end.Month && start.Month == month)
                {
                    if (start.Day <= day && day <= end.Day)
                    {
                        this.UpcomingBirthday = true;
                        return;
                    }
                }

                if ((start.Month != end.Month) && (start.Month == month || end.Month == month))
                {
                    if (start.Month == month)
                    {
                        if (start.Day <= day)
                        {
                            this.UpcomingBirthday = true;
                            return;
                        }
                    }
                    else
                    {
                        if (day <= end.Day)
                        {
                            this.UpcomingBirthday = true;
                            return;
                        }
                    }
                }                
            }

            this.UpcomingBirthday = false;
        }
    }
}
